package com.youxin.cpcenter.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.youxin.busfoundation.bean.ResponseObject;
import com.youxin.busfoundation.bean.login.UserInfo;
import com.youxin.busfoundation.bean.phone.QueryMiddlePhone;
import com.youxin.busfoundation.bean.phone.RequestBillsBean;
import com.youxin.busfoundation.bean.phone.RequestPhoneBean;
import com.youxin.busfoundation.bean.phone.RequestPhoneCallBack;
import com.youxin.busfoundation.bean.phone.ResponseBillsBean;
import com.youxin.busfoundation.bean.phone.ResponseBindMobile;
import com.youxin.busfoundation.bean.phone.TelphoneResultBean;
import com.youxin.busfoundation.common.BusinessException;
import com.youxin.busfoundation.common.GlobalConfig;
import com.youxin.busfoundation.common.LoginAuth;
import com.youxin.busfoundation.common.redis.RedisOperator;
import com.youxin.busfoundation.enums.EntConsumeTypeEnums;
import com.youxin.busfoundation.enums.EnterpriseIdentityType;
import com.youxin.busfoundation.net.WebVisitor;
import com.youxin.busfoundation.utils.security.AesUtils;
import com.youxin.cpcenter.dao.TbEntMemberIdentifyCapitalMapper;
import com.youxin.cpcenter.dao.TbEntMemberIdentifyMapper;
import com.youxin.cpcenter.dao.TbEntMiddlePhoneMapper;
import com.youxin.cpcenter.dao.TbEntOrderMiddlePhoneRecordMapper;
import com.youxin.cpcenter.dao.TbMemberInfoMapper;
import com.youxin.cpcenter.model.TbEntConsume;
import com.youxin.cpcenter.model.TbEntMemberIdentify;
import com.youxin.cpcenter.model.TbEntMiddlePhone;
import com.youxin.cpcenter.model.TbEntOrderMiddlePhoneRecord;
import com.youxin.cpcenter.model.TbMemberInfo;
import com.youxin.cpcenter.service.CouponService;
import com.youxin.cpcenter.service.EntConsumeService;
import com.youxin.cpcenter.service.TelphoneService;
import com.youxin.cpcenter.utils.MemberRightsUtils;
import com.youxin.foundation.db.utils.KeyGenerationUtils;
import com.youxin.foundation.utils.HashUtils;
import com.youxin.foundation.utils.RegexUtils;
import com.youxin.foundation.utils.StringUtils;
import com.youxin.foundation.utils.collections.CollectionsUtils;

/**
 * 电话接口
 * 
 * @author yingde.cao
 *
 */
@Service("telphoneService")
public class TelphoneServiceImpl extends BaseServiceImpl implements TelphoneService {
	private final static int EXPIRE_TIME = GlobalConfig.TELEPHONE_EXPIRE_TIME;
	@Autowired
	private CouponService couponService;
	@Autowired
	private TbMemberInfoMapper tbMemberInfoMapper;
	@Autowired
	private TbEntMiddlePhoneMapper tbEntMiddlePhoneMapper;
	@Autowired
	private TbEntOrderMiddlePhoneRecordMapper tbEntOrderMiddlePhoneRecordMapper;
	// @Autowired
	// private TbEntMemberIdentifyCapitalMapper
	// tbEntMemberIdentifyCapitalMapper;
	@Autowired
	private TbEntMemberIdentifyMapper tbEntMemberIdentifyMapper;
	@Autowired
	private EntConsumeService entConsumeService;

	@Transactional(propagation = Propagation.REQUIRED)
	public ResponseObject call(RequestPhoneBean bean) {
		UserInfo userInfo = LoginAuth.getUserInfo();
		TbMemberInfo memberInfo = MemberRightsUtils.isMemberIdentifyAndPassed(tbMemberInfoMapper);
		String phone = memberInfo.getPhone();

		// bean.setTo("18679613442");
		// AesUtils.main2(null);
		String to = AesUtils.decrypt(bean.getTo(), String.valueOf(userInfo.getId()));
		if (!StringUtils.isNullOrEmpty(to)) {
			bean.setTo(to);
		}
		if (phone.equals(bean.getTo())) {
			throw new BusinessException("拨打电话号码和接收电话号码一致");
		}
		if (!RegexUtils.isMobile(bean.getTo())) {
			throw new BusinessException("手机号码格式错误");
		}
		if (!RegexUtils.isMobile(phone)) {
			throw new BusinessException("当前会员手机号码为空,无法绑定");
		}
		if (!couponService.isCanConsumer(userInfo.getEntIdentifyId())) {
			throw new BusinessException("企业金券余额不足");
		}
		/**
		 * 查询已经绑定的记录
		 */
		String oldSubid = RedisOperator.getOldCallBind(userInfo.getEntMemberId());
		if (!StringUtils.isNullOrEmpty(oldSubid)) {
			RequestPhoneBean tempBean = new RequestPhoneBean();
			tempBean.setSubid(oldSubid);			
			TbEntMiddlePhone entMiddlePhone = tbEntMiddlePhoneMapper.selectBySubid(oldSubid);
			if (entMiddlePhone != null) {
				if (entMiddlePhone.getAnswerPhone().equals(bean.getTo())) {
					 ResponseBindMobile responseBindMobile=queryHistory(entMiddlePhone);
					 if(responseBindMobile.getExpires()>=10)
					 {
						 return ResponseObject.successObject(responseBindMobile);
					 }
				}
			}
			unbind(tempBean);
		}

		// ResponseBindMobile responseBindMobile=queryHistory(phone, bean.getTo());
		// if(!StringUtils.isNullOrEmpty(responseBindMobile.getMiddlePhone())&&responseBindMobile.getExpires()>=0){
		// return ResponseObject.successObject(responseBindMobile);
		// }

		Map<String, String> paramMap = new LinkedHashMap<>();
		paramMap.put("appid", GlobalConfig.TELPHONE_APPID);
		paramMap.put("telA", phone);
		paramMap.put("telB", bean.getTo());
		paramMap.put("expiration", String.valueOf(EXPIRE_TIME));
		paramMap.put("callrecording", "1");
		paramMap.put("areacode", "755");
		String paramterString = CollectionsUtils.mapToString(paramMap, "=", "&");
		String sign = sign(paramMap);
		String urlString = GlobalConfig.TELPHONE_BASE_URL + "rms/unicomAxBBind?" + paramterString + "&sign=" + sign;

		TelphoneResultBean result = WebVisitor.instance().httpGetToEntity(urlString, TelphoneResultBean.class);

		if (result == null) {
			return ResponseObject.userFailure("绑定号码失败");
		}

		if (result.getResult() == 0) {
			String subid = result.getData().getSubid();
			RedisOperator.saveCallBind(userInfo.getEntMemberId(), subid, EXPIRE_TIME);
			TbEntMiddlePhone tbEntMiddlePhone = new TbEntMiddlePhone();
			tbEntMiddlePhone.setId(KeyGenerationUtils.generateKey());
			tbEntMiddlePhone.setEntIdentifyId(userInfo.getEntIdentifyId());
			tbEntMiddlePhone.setCallPhone(phone);
			tbEntMiddlePhone.setAnswerPhone(bean.getTo());
			tbEntMiddlePhone.setMemberId(memberInfo.getId());
			tbEntMiddlePhone.setMemberName(StringUtils.isNullOrEmptySet(memberInfo.getRealname(),memberInfo.getUsername()));
			tbEntMiddlePhone.setEntMemberId(userInfo.getEntMemberId());
			tbEntMiddlePhone.setContactMemberId(bean.getToMemberId());
			tbEntMiddlePhone.setContactMemberName(StringUtils.isNullSetEmpty(bean.getToMemberName()));
			tbEntMiddlePhone.setCompanyName(StringUtils.isNullSetEmpty(bean.getCompanyName()));
			tbEntMiddlePhone.setCompanyUid(StringUtils.isNullSetEmpty(bean.getCompanyUid()));
			tbEntMiddlePhone.setMiddlePhone(result.getData().getTelX());
			tbEntMiddlePhone.setSubid(subid);
			tbEntMiddlePhone.setCreateTime(new Date());
			tbEntMiddlePhone.setExpiredSecond(EXPIRE_TIME);
			int rowEffected = tbEntMiddlePhoneMapper.insertSelective(tbEntMiddlePhone);
			if (rowEffected != 1) {
				return ResponseObject.userFailure("绑定号码失败");
			}

			ResponseBindMobile responseBindMobile = new ResponseBindMobile();
			responseBindMobile.setExpires(EXPIRE_TIME);
			responseBindMobile.setSubid(tbEntMiddlePhone.getSubid());
			responseBindMobile.setMiddlePhone(tbEntMiddlePhone.getMiddlePhone());

			return ResponseObject.successObject(responseBindMobile);

		} else if (result.getResult() == 1) {

			ResponseBindMobile responseBindMobile = queryHistory(phone, bean.getTo());
			return ResponseObject.successObject(responseBindMobile);
		}
		return ResponseObject.userFailure("绑定号码失败");
	}

	private ResponseBindMobile queryHistory(String from, String to) {
		QueryMiddlePhone queryMiddlePhone = new QueryMiddlePhone();
		queryMiddlePhone.setCallPhone(from);
		queryMiddlePhone.setAnswerPhone(to);
		TbEntMiddlePhone entMiddlePhone = tbEntMiddlePhoneMapper.selectByPhones(queryMiddlePhone);
		ResponseBindMobile responseBindMobile = new ResponseBindMobile();
		if (entMiddlePhone != null) {
			responseBindMobile.setMiddlePhone(entMiddlePhone.getMiddlePhone());
			responseBindMobile.setSubid(entMiddlePhone.getSubid());
			long expiresMs = entMiddlePhone.getCreateTime().getTime()
					+ entMiddlePhone.getExpiredSecond().longValue() * 1000L - System.currentTimeMillis();
			responseBindMobile.setExpires(expiresMs / 1000L);
		}
		return responseBindMobile;
	}

	private ResponseBindMobile queryHistory(String subid) {
		TbEntMiddlePhone entMiddlePhone = tbEntMiddlePhoneMapper.selectBySubid(subid);
		if (entMiddlePhone != null) {
			return queryHistory(entMiddlePhone);
		}
		return null;
	}

	private ResponseBindMobile queryHistory(TbEntMiddlePhone entMiddlePhone) {

		ResponseBindMobile responseBindMobile = new ResponseBindMobile();
		responseBindMobile.setMiddlePhone(entMiddlePhone.getMiddlePhone());
		responseBindMobile.setSubid(entMiddlePhone.getSubid());
		long expiresMs = entMiddlePhone.getCreateTime().getTime()
				+ entMiddlePhone.getExpiredSecond().longValue() * 1000L - System.currentTimeMillis();
		responseBindMobile.setExpires(expiresMs / 1000L);
		return responseBindMobile;

	}

	/**
	 * 解绑号码接口
	 */
	public ResponseObject unbind(RequestPhoneBean bean) {
		Map<String, String> paramMap = new LinkedHashMap<>();
		paramMap.put("appid", GlobalConfig.TELPHONE_APPID);
		paramMap.put("subid", bean.getSubid());
		String paramterString = CollectionsUtils.mapToString(paramMap, "=", "&");
		String sign = sign(paramMap);
		String urlString = GlobalConfig.TELPHONE_BASE_URL + "rms/unicomAxBUnBind?" + paramterString + "&sign=" + sign;
		TelphoneResultBean result = WebVisitor.instance().httpGetToEntity(urlString, TelphoneResultBean.class);
		if (result == null) {
			return ResponseObject.userFailure("解绑号码失败");
		}
		if (result.getResult() == 0 || result.getResult() == 1) {
			return ResponseObject.successObject();
		}
		return ResponseObject.userFailure("解绑号码失败");
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public ResponseObject saveResult(RequestPhoneCallBack bean) {
		if (StringUtils.isNullOrEmpty(bean.getStarttime())) {
			return ResponseObject.successObject();
		}
		TbEntMiddlePhone entity = tbEntMiddlePhoneMapper.selectBySubid(bean.getSubid());
		if (entity == null) {
			throw new BusinessException("没有查询到中间号关联记录");
		}
		TbEntMemberIdentify entMemberIdentify = tbEntMemberIdentifyMapper.selectByPrimaryKey(entity.getEntIdentifyId());

		String subid = bean.getSubid();
		long memberId = entity.getMemberId();
		long entMemberId = entity.getEntMemberId();
		String memberName = entity.getMemberName();
		long contactId = entity.getContactMemberId();
		// String contactUid = "";
		String orderSn = "";
		BigDecimal basePoint = new BigDecimal(0);
		BigDecimal coupon = getCouponCoin(bean, entMemberIdentify.getIdentyType());
		TbEntOrderMiddlePhoneRecord record = new TbEntOrderMiddlePhoneRecord();
		record.setId(KeyGenerationUtils.generateKey());
		record.setEntIdentifyId(entity.getEntIdentifyId());
		record.setCallid(bean.getCallid());
		record.setMemberId(memberId);
		record.setEntMemberId(entMemberId);
		record.setMemberName(memberName);
		record.setContactMemberId(contactId);
		record.setContactMemberName(entity.getContactMemberName());
		record.setCompanyName(entity.getCompanyName());
		record.setCompanyUid(entity.getCompanyUid());
		record.setCallPhone(bean.getTelA());
		record.setAnswerPhone(bean.getTelB());
		record.setSubid(subid);
		record.setMiddlePhone(bean.getTelX());
		record.setRecordUrl(bean.getRecordUrl());
		record.setOrderSn(orderSn);
		record.setCallMinute(bean.getCallTimeMinutes());
		record.setCallSecond(bean.getCallTimeSeconds());
		record.setBasePoint(basePoint);
		record.setCoupon(coupon);
		record.setIsNotify(0);
		long time = System.currentTimeMillis();
		record.setAddTime(time);
		record.setUpdateTime(time);
		int rowEffected = tbEntOrderMiddlePhoneRecordMapper.insertSelective(record);
		if (rowEffected != 1) {
			throw new BusinessException("保存回调异常");
		}
		if (coupon.compareTo(BigDecimal.ZERO) > 0) {
			couponService.decreaseCoupon(entity.getEntIdentifyId(), coupon);
		}
//		try {
			// 保存到 企业消费记录
			TbEntConsume consumeModel = new TbEntConsume();
			consumeModel.setMiddlePhoneId(record.getId());
			int seconds = bean.getCallTimeSeconds();//bean.getCallTimeMinutes() * 60 
			
			consumeModel.setCountNum(String.valueOf(seconds));
			consumeModel.setCallerUserId(record.getMemberId());
			consumeModel.setCallerUserName(record.getMemberName());
			consumeModel.setCallerUserPhone(record.getCallPhone());
			consumeModel.setCompanyFullName(record.getCompanyName());
			consumeModel.setCompanyUid(record.getCompanyUid());
			consumeModel.setEntIdentifyId(record.getEntIdentifyId());
			consumeModel.setEntMemberId(entMemberId);
			consumeModel.setCalledUserId(record.getContactMemberId());
			consumeModel.setCalledUserName(record.getContactMemberName());
			consumeModel.setCalledUserPhone(record.getAnswerPhone());
			consumeModel.setConsumeType(EntConsumeTypeEnums.SJLX.getIndex());
			EnterpriseIdentityType type = EnterpriseIdentityType.valueOf(entMemberIdentify.getIdentyType());
			BigDecimal unitPrice = type.getCallsPerMinute();
			consumeModel.setUnitPrice(unitPrice);
			consumeModel.setConsumeAmount(coupon);
			entConsumeService.insertEntConsume(consumeModel);
		// } catch (Exception e) {
		// logger.error("保存消费记录异常:",e);
		// }

		return ResponseObject.successObject();
	}

	/**
	 * 查询账单
	 */
	public ResponseObject bills(RequestBillsBean bean) {
		ResponseBillsBean obj = tbEntOrderMiddlePhoneRecordMapper.selectBySubidSum(bean.getSubid());
		if (obj == null) {
			obj = new ResponseBillsBean();
		}
		return new ResponseObject(obj);
	}

	private BigDecimal getCouponCoin(RequestPhoneCallBack bean, short identifyType) {
		EnterpriseIdentityType type = EnterpriseIdentityType.valueOf(identifyType);
		int minutes = bean.getCallTimeMinutes();// + bean.getCallTimeSeconds() == 0 ? 0 : 1;
		BigDecimal minutesDecimal = new BigDecimal(minutes);
		BigDecimal result = minutesDecimal.multiply(type.getCallsPerMinute());
		return result;
	}

	private static String sign(Map<String, String> params) {
		String sortParamsValues = params.values().stream().filter(s -> s != null && !s.equals("")).sorted()
				.collect(Collectors.joining());
		return HashUtils.sha1(sortParamsValues + GlobalConfig.TELPHONE_APPKEY);
	}
}
